// 命令行程序支持组件
// 此组件需要使用 xconsole.Listen() 来运行命令监听，即：
//
//	if len(os.Args) > 1 {
//		xconsole.Listen()
//		return
//	}
package xconsole

import (
	"fmt"
	"sync"
)

// 命令支持的函数结构
type Command func(help bool) string

// 配置项
type Config struct {
	Version       string                  // 外部版本标识
	Rout          map[string]Command      // 注入时直接携带路由进行注入
	WriteFileFunc func(name, body string) // 写入文件的函数，外部注册时可直接注册为：xfile.WriteString
	FmtFunc       func(file ...string)    // 格式化文件的函数，若未注入则需要手动进行执行此命令
	v             string                  // 内部版本标识
	r             map[string]Command      // 内部路由
	l             sync.Mutex              // 内部路由锁
}

// 默认配置
var _default Config = Config{
	r:       map[string]Command{},
	l:       sync.Mutex{},
	v:       "v0.1",
	Version: "v1.0.0",
}

// 初始化函数，用于注入原生支持的命令
func init() {
	Push("v", version)                                      // 版本检测
	Push("version", version)                                // 版本检测
	Push("mkgorm", mkGorm)                                  // 创建Gorm模型
	Push("json2model", json2model)                          // JSON转结构体模型
	Push("kstruct", kstruct)                                // 单独字段转为Struct结构体
	Push("cpp", cpp)                                        // 生成参数结构体信息
	Push("mkgrub", mkGRUB)                                  // 添加GRUB操作及相关模型等信息
	Push("interface-encapsulation", interfaceEncapsulation) // http接口转发
}

// 写入文件
//
//	name	文件名
//	body	写入结构体
func writeFile(name, body string) {
	if _default.WriteFileFunc != nil {
		fmt.Println("生成文件：" + name)
		_default.WriteFileFunc(name, body)
	} else {
		fmt.Println("抱歉，暂未找到写入文件的注入函数，请注入写入函数后再次尝试，或手动复制到对应文件中")
		fmt.Println("filename: " + name + "\n")
		fmt.Println(body)
	}
}

// 格式化go代码工具
//
//	file	待格式化的文件
func fmtFunction(file ...string) {
	if _default.FmtFunc == nil {
		fmt.Println("暂未找到格式化函数，请手动执行以下命令：")
		for i := 0; i < len(file); i++ {
			fmt.Print("go fmt " + file[i] + "; ")
		}
	} else {
		_default.FmtFunc(file...)
	}
}

// 注入配置
func Regedit(conf *Config) {
	if conf == nil {
		return
	}
	if conf.Version != "" {
		_default.Version = conf.Version
	}
	if conf.Rout != nil {
		PushMap(conf.Rout)
	}
	if conf.WriteFileFunc != nil {
		_default.WriteFileFunc = conf.WriteFileFunc
	}
	if conf.FmtFunc != nil {
		_default.FmtFunc = conf.FmtFunc
	}
}
